/**
 * 问答模型类 - 对接百度千帆API
 */
class QAModel {
    /**
     * 构造函数
     */
    constructor() {
        // API密钥配置 - 严格使用截图中的密钥
        this.API_KEY = 'UohB9sPnu3cmLwv6xUxLsGrx';
        this.SECRET_KEY = 'nKxqleOKYmah4mFdz9t2pMM0xzk8WKlw';
        
        // API基础URL - 根据新截图修改为正确的域名
        this.BASE_URL = 'https://aip.baidubce.com';
        
        // 访问令牌
        this._accessToken = '';
        this._tokenExpireTime = 0;
    }
    
    /**
     * 获取秒级时间戳
     * @private
     */
    _getTimestamp() {
        return Math.floor(Date.now() / 1000);
    }

    /**
     * 提问问题并获取回答
     * @param {string} question - 用户问题
     */
    async askQuestion(question) {
        try {
            console.log('【QA】接收到问题:', question);
            
            if (!question || question.trim().length === 0) {
                return {
                    code: 1,
                    result: '请输入您的问题'
                };
            }
            
            // 根据开发环境决定调用策略
            const envVersion = wx.getAccountInfoSync().miniProgram.envVersion;
            console.log('【QA】当前环境:', envVersion);
            
            // 环境版本提示
            if (envVersion === 'develop') {
                console.log('【QA】开发环境: 请确保已在开发者工具中勾选"不校验合法域名"选项');
            } else {
                console.log('【QA】生产环境: 请确保已在微信公众平台添加aip.baidubce.com到合法域名');
            }
            
            try {
                // 尝试调用API
                console.log('【QA】尝试通过API回答问题');
                const apiResponse = await this._callQianfanAPI(question);
                
                if (apiResponse) {
                    console.log('【QA】成功通过API获取回答');
                    return apiResponse;
                }
            } catch (apiError) {
                console.error('【QA】API调用失败, 错误详情:', apiError);
            }
            
            // API调用失败，使用本地回答
            console.log('【QA】使用本地回答');
            return {
                code: 0,
                result: {
                    answer: this._getLocalAnswer(question),
                    references: []
                }
            };
        } catch (err) {
            console.error('【QA】处理问题时出错:', err);
            return {
                code: 1,
                result: '抱歉，处理您的问题时出现错误，请稍后再试'
            };
        }
    }
    
    /**
     * 调用百度千帆API
     * @private
     */
    async _callQianfanAPI(question, history = []) {
        try {
            console.log('【QA】开始调用千帆API...');
            
            // 获取访问令牌
            const token = await this._getAccessToken();
            if (!token) {
                console.error('【QA】无法获取访问令牌，切换到本地回答');
                return {
                    code: 0,
                    result: {
                        answer: this._getLocalAnswer(question),
                        references: []
                    }
                };
            }
            
            // 使用百度千帆v2版API接口
            const apiUrl = `${this.BASE_URL}/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=${token}`;
            console.log('【QA】请求URL:', apiUrl);
            
            // 构建发送给模型的消息
            const messages = [];
            
            /* 百度千帆API要求第一条消息必须是user或assistant角色
            // 添加system角色指令
            messages.push({
                role: 'system',
                content: '你是一位电力系统专家，专长于电力系统的规划、运行、维护和故障处理。请用专业、准确、简洁的方式回答用户关于电力系统的问题。'
            });
            */
            
            // 添加历史对话
            if (history && history.length > 0) {
                history.forEach(item => {
                    messages.push({
                        role: 'user',
                        content: item.question
                    });
                    messages.push({
                        role: 'assistant',
                        content: item.answer
                    });
                });
            }
            
            // 添加当前问题，如果没有历史对话，这将是第一条消息
            messages.push({
                role: 'user',
                content: '你是一位电力系统专家，请用专业、准确、简洁的方式回答我的问题：' + question
            });
            
            // 构建请求体
            const requestData = {
                messages: messages,
                temperature: 0.7,
                top_p: 0.9,
                stream: false
            };
            
            console.log('【QA】请求参数:', JSON.stringify(requestData));
            
            // 最大重试次数
            const maxRetries = 3;
            let retryCount = 0;
            let lastError = null;
            let apiCallSuccess = false; // 跟踪是否成功调用了API
            
            // 返回Promise以确保正确处理响应
            return new Promise((resolve, reject) => {
                const makeRequest = () => {
                    // 如果已达到最大重试次数，使用本地回答
                    if (retryCount >= maxRetries) {
                        console.error(`【QA】已达到最大重试次数(${maxRetries})，切换到本地回答`);
                        if (lastError) {
                            console.error('【QA】最后一次错误:', lastError);
                        }
                        return resolve({
                            code: 0,
                            result: {
                                answer: this._getLocalAnswer(question),
                                references: []
                            }
                        });
                    }
                    
                    // 重试时添加延迟 - 使用指数退避策略，基础延迟3秒，然后按倍数增加
                    const retryDelay = (retryCount === 0) ? 0 : 3000 * Math.pow(2, retryCount - 1); // 0, 3000, 6000ms
                    
                    if (retryCount > 0) {
                        console.log(`【QA】第${retryCount}次重试，延迟${retryDelay}毫秒...`);
                    }
                    
                    setTimeout(() => {
                        wx.request({
                            url: apiUrl,
                            method: 'POST',
                            header: {
                                'Content-Type': 'application/json'
                            },
                            data: requestData,
                            success: (res) => {
                                console.log('【QA】API响应状态码:', res.statusCode);
                                console.log('【QA】API完整响应:', JSON.stringify(res.data));
                                
                                // 检查API调用是否成功
                                if (res.statusCode === 200 && res.data && res.data.result) {
                                    const answer = res.data.result;
                                    console.log('【QA】成功通过API获取回答');
                                    
                                    // 只有成功获取回答才记录API使用次数
                                    apiCallSuccess = true;
                                    this._recordAPIUsage();
                                    
                                    resolve({
                                        code: 0,
                                        result: {
                                            answer: answer,
                                            references: []
                                        }
                                    });
                                } 
                                // 处理QPS限制错误
                                else if (res.data && res.data.error_code === 18 && res.data.error_msg === "Open api qps request limit reached") {
                                    console.warn('【QA】API请求频率超限，等待后重试');
                                    lastError = "请求频率超限: " + res.data.error_msg;
                                    
                                    // QPS错误达到最后一次重试时，直接返回本地答案
                                    if (retryCount >= maxRetries - 1) {
                                        console.warn('【QA】QPS限制持续存在，直接切换到本地回答');
                                        return resolve({
                                            code: 0,
                                            result: {
                                                answer: this._getLocalAnswer(question),
                                                references: []
                                            }
                                        });
                                    }
                                    
                                    retryCount++;
                                    // 指数退避重试
                                    makeRequest();
                                } 
                                else {
                                    console.error('【QA】API响应异常，切换到本地回答');
                                    console.error('【QA】错误详情:', res.data && res.data.error_msg ? res.data.error_msg : '未知错误');
                                    
                                    // 检查是否应该重试其他类型的错误
                                    if (res.data && res.data.error_code) {
                                        lastError = `错误码: ${res.data.error_code}, 消息: ${res.data.error_msg || '未知'}`;
                                        // 仅针对可恢复的错误进行重试
                                        if ([18, 110, 111, 336100].includes(res.data.error_code)) {
                                            // 最后一次重试直接放弃
                                            if (retryCount >= maxRetries - 1) {
                                                console.warn(`【QA】错误${res.data.error_code}持续存在，直接切换到本地回答`);
                                                return resolve({
                                                    code: 0,
                                                    result: {
                                                        answer: this._getLocalAnswer(question),
                                                        references: []
                                                    }
                                                });
                                            }
                                            
                                            retryCount++;
                                            makeRequest();
                                            return;
                                        }
                                    }
                                    
                                    resolve({
                                        code: 0,
                                        result: {
                                            answer: this._getLocalAnswer(question),
                                            references: []
                                        }
                                    });
                                }
                            },
                            fail: (err) => {
                                console.error('【QA】API调用网络异常，尝试重试:', err);
                                if (err.errMsg) {
                                    console.error('【QA】错误消息:', err.errMsg);
                                }
                                
                                lastError = err.errMsg || '网络请求失败';
                                
                                // 最后一次重试网络失败直接本地回答
                                if (retryCount >= maxRetries - 1) {
                                    console.warn('【QA】网络持续异常，直接切换到本地回答');
                                    return resolve({
                                        code: 0,
                                        result: {
                                            answer: this._getLocalAnswer(question),
                                            references: []
                                        }
                                    });
                                }
                                
                                // 网络错误通常可以重试
                                retryCount++;
                                makeRequest();
                            }
                        });
                    }, retryDelay);
                };
                
                // 开始第一次请求
                makeRequest();
            });
        } catch (err) {
            console.error('【QA】API调用异常，切换到本地回答:', err);
            if (err.errMsg) {
                console.error('【QA】错误消息:', err.errMsg);
            }
            
            return {
                code: 0,
                result: {
                    answer: this._getLocalAnswer(question),
                    references: []
                }
            };
        }
    }
    
    /**
     * 获取访问令牌
     * @private
     */
    async _getAccessToken() {
        try {
            // 检查是否有未过期的token
            const now = this._getTimestamp();
            if (this._accessToken && this._tokenExpireTime > now) {
                console.log('【QA】使用缓存的访问令牌');
                return this._accessToken;
            }

            console.log('【QA】开始获取访问令牌...');
            
            // 完全一致的URL
            const url = `${this.BASE_URL}/oauth/2.0/token?grant_type=client_credentials&client_id=${this.API_KEY}&client_secret=${this.SECRET_KEY}`;
            
            console.log('【QA】访问令牌请求URL:', url);
            
            // 返回Promise以便await
            return new Promise((resolve, reject) => {
                wx.request({
                    url: url,
                    method: 'GET',
                    success: (res) => {
                        console.log('【QA】访问令牌请求结果状态码:', res.statusCode);
                        console.log('【QA】访问令牌完整响应:', JSON.stringify(res.data));
                        
                        if (res.statusCode === 200 && res.data && res.data.access_token) {
                            this._accessToken = res.data.access_token;
                            // 设置过期时间（提前5分钟过期，避免临界点问题）
                            this._tokenExpireTime = now + res.data.expires_in - 300;
                            console.log('【QA】成功获取访问令牌，有效期至:', new Date((this._tokenExpireTime) * 1000).toLocaleString());
                            resolve(this._accessToken);
                        } else {
                            console.error('【QA】获取访问令牌失败 - 响应数据异常:', JSON.stringify(res.data));
                            if (res.data && res.data.error) {
                                console.error('【QA】错误代码:', res.data.error);
                                console.error('【QA】错误描述:', res.data.error_description);
                            }
                            resolve(null);
                        }
                    },
                    fail: (err) => {
                        console.error('【QA】获取访问令牌出现网络异常:', err);
                        if (err.errMsg) {
                            console.error('【QA】错误消息:', err.errMsg);
                        }
                        resolve(null);
                    }
                });
            });
        } catch (err) {
            console.error('【QA】获取访问令牌出现异常:', err);
            if (err.errMsg) {
                console.error('【QA】错误消息:', err.errMsg);
            }
            return null;
        }
    }
    
    /**
     * 测试连接
     * @returns {Promise<object>} 连接测试结果
     */
    async testConnection() {
        try {
            console.log('【QA】开始测试百度千帆API连接...');
            const token = await this._getAccessToken();
            if (token) {
                console.log('【QA】API连接测试成功，成功获取访问令牌');
                return {
                    status: true,
                    message: '连接成功，已获取访问令牌'
                };
            } else {
                console.error('【QA】API连接测试失败，无法获取访问令牌');
                return {
                    status: false,
                    message: '连接失败，无法获取访问令牌'
                };
            }
        } catch (err) {
            console.error('【QA】API连接测试异常:', err);
            return {
                status: false,
                message: '连接测试发生异常: ' + (err.errMsg || err.message || '未知错误')
            };
        }
    }

    /**
     * 获取本地回答
     * @param {string} question 问题内容
     * @returns {string} 本地回答
     * @private
     */
    _getLocalAnswer(question) {
        if (!question) return '请输入您的问题';

        // 转换问题为小写，便于匹配
        const normalizedQ = question.toLowerCase().trim();

        // 根据关键词匹配回答
        if (normalizedQ.includes('变压器') || normalizedQ.includes('transformer')) {
            return '变压器是电力系统中的关键设备，用于改变交流电压。主要类型包括：\n1. 电力变压器：用于输电系统\n2. 配电变压器：用于配电网络\n3. 特种变压器：如整流变压器、电炉变压器等\n变压器的主要参数包括额定容量、额定电压、阻抗电压等。维护时需定期检查绝缘油质量、套管清洁度及各连接部位。';
        }

        if (normalizedQ.includes('电力系统') || normalizedQ.includes('power system')) {
            return '电力系统是由发电、输电、变电、配电和用电等环节组成的电能生产和消费系统。现代电力系统通常包括发电厂、变电站、输电线路、配电网络和终端用户。电力系统的稳定运行对国民经济和人民生活至关重要，需要通过各种自动化和智能化技术保障其安全可靠运行。';
        }

        if (normalizedQ.includes('故障') || normalizedQ.includes('fault')) {
            return '电力系统常见故障类型包括：\n1. 短路故障：包括单相接地、两相短路、两相接地短路和三相短路\n2. 断线故障：包括单相断线和多相断线\n3. 系统稳定故障：如功角稳定问题和电压稳定问题\n4. 设备故障：如变压器、断路器、避雷器等设备损坏\n\n故障处理通常需要根据故障类型采取不同的保护措施和修复策略。';
        }

        if (normalizedQ.includes('稳定') || normalizedQ.includes('stability')) {
            return '提高电力系统稳定性的方法包括：\n1. 增强网络结构：新建输电线路，加强网络互联\n2. 应用先进控制技术：如PSS（电力系统稳定器）、FACTS（柔性交流输电系统）\n3. 合理调整运行方式：优化功率潮流分布\n4. 提高设备性能：如增加发电机组的惯性时间常数\n5. 采用智能保护与控制系统：快速识别故障并采取相应措施';
        }

        if (normalizedQ.includes('智能电网') || normalizedQ.includes('smart grid')) {
            return '智能电网是采用先进传感测量技术、通信技术、信息技术、计算机技术和控制技术的新型电网。其特点包括：\n1. 自愈能力：可自动检测、分析、响应和恢复故障\n2. 激励和吸纳消费者参与：支持分布式能源接入和需求侧管理\n3. 抵御攻击：具有较强的物理和网络安全防护能力\n4. 提供满足21世纪需求的电能质量\n5. 容纳各种发电形式：支持可再生能源的大规模接入\n6. 启动电力市场：促进零售和批发市场创新\n7. 资产优化高效运行';
        }

        if (normalizedQ.includes('电气设备') || normalizedQ.includes('electrical equipment')) {
            return '电力系统中的主要电气设备包括：\n1. 发电设备：如汽轮发电机组、水轮发电机组等\n2. 输电设备：如架空线路、电缆、电抗器、电容器等\n3. 变电设备：如变压器、断路器、隔离开关、互感器等\n4. 配电设备：如配电变压器、配电柜、断路器等\n5. 保护和控制设备：如继电保护装置、自动化系统等\n\n这些设备的正常运行和维护对确保电力系统安全稳定运行至关重要。';
        }

        if (normalizedQ.includes('发电') || normalizedQ.includes('generation')) {
            return '电力系统中的发电方式主要包括：\n1. 火力发电：包括煤电、燃气、燃油等，目前仍是主要发电方式\n2. 水力发电：利用水的势能转化为电能，是重要的可再生能源\n3. 核能发电：利用核裂变释放的热能发电，具有高效、清洁的特点\n4. 风力发电：利用风能转化为电能，是发展最快的可再生能源之一\n5. 太阳能发电：包括光伏发电和光热发电，是清洁能源的重要组成\n6. 其他新能源：如生物质能、地热能、潮汐能等\n\n各种发电方式有不同的特点和适用条件，电力系统通常采用多种发电方式互补运行。';
        }

        // 通用回答
        return '感谢您的提问。针对您询问的电力系统相关问题，建议您参考专业电力工程手册或咨询电力系统专业工程师以获取更准确的信息。您也可以尝试更换提问方式，或者在问题中包含"变压器"、"电力系统"、"故障"、"稳定性"、"智能电网"等关键词以获取基础信息。';
    }

    /**
     * 延迟函数
     * @param {number} ms 延迟毫秒数
     * @returns {Promise<void>}
     * @private
     */
    _delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * 检查API配额使用情况
     * @returns {Promise<object>} 配额使用情况
     */
    async checkAPIQuota() {
        try {
            console.log('【QA】开始检查API配额使用情况...');
            
            // 获取访问令牌
            const token = await this._getAccessToken();
            if (!token) {
                console.error('【QA】无法获取访问令牌，无法检查配额');
                return {
                    status: false,
                    message: '无法获取访问令牌，请检查网络连接',
                    quota: {
                        used: 0,
                        available: 0,
                        isExceeded: false
                    }
                };
            }
            
            // 使用百度千帆API查询配额
            const quotaUrl = `${this.BASE_URL}/rpc/2.0/ai_custom/v1/wenxinworkshop/api/usage?access_token=${token}`;
            console.log('【QA】配额查询URL:', quotaUrl);
            
            // 返回Promise以便await
            return new Promise((resolve, reject) => {
                wx.request({
                    url: quotaUrl,
                    method: 'GET',
                    success: (res) => {
                        console.log('【QA】配额查询结果状态码:', res.statusCode);
                        console.log('【QA】配额查询完整响应:', JSON.stringify(res.data));
                        
                        if (res.statusCode === 200) {
                            // 免费用户和付费用户接口返回的数据结构可能不同
                            if (res.data.error_code) {
                                // 如果返回错误，可能是免费额度没有配额查询接口
                                console.log('【QA】API不支持配额查询或为免费用户');
                                
                                // 尝试从本地存储获取使用情况
                                const usageInfo = this._getStoredUsage();
                                resolve({
                                    status: true,
                                    message: '您正在使用免费账号，无法精确查询配额',
                                    quota: {
                                        used: usageInfo.used || 0,
                                        available: '免费版本限制QPS=1',
                                        daily: '50次/天 (估计值)',
                                        plan: '免费版',
                                        isExceeded: false
                                    }
                                });
                            } else {
                                // 成功获取配额信息
                                const quotaData = res.data;
                                
                                // 解析返回数据，不同模型的配额格式可能不同
                                let quota = {
                                    used: 0,
                                    available: 0,
                                    daily: '未知',
                                    plan: '付费版',
                                    isExceeded: false
                                };
                                
                                // 填充配额信息
                                if (quotaData.usage) {
                                    quota.used = quotaData.usage.amount || 0;
                                    quota.available = quotaData.usage.limit || 0;
                                    quota.isExceeded = quota.used >= quota.available;
                                    quota.daily = `${quota.available}次/天`;
                                    quota.plan = quotaData.usage.plan || '付费版';
                                }
                                
                                resolve({
                                    status: true,
                                    message: '成功获取API配额信息',
                                    quota: quota
                                });
                            }
                        } else {
                            // 如果状态码不是200，可能是无权限或其他错误
                            console.error('【QA】获取配额失败 - 响应数据异常:', JSON.stringify(res.data));
                            
                            resolve({
                                status: false,
                                message: `查询配额失败: ${res.data.error_msg || '未知错误'}`,
                                quota: {
                                    used: 0,
                                    available: 0,
                                    daily: '未知',
                                    isExceeded: false
                                }
                            });
                        }
                    },
                    fail: (err) => {
                        console.error('【QA】获取配额出现网络异常:', err);
                        if (err.errMsg) {
                            console.error('【QA】错误消息:', err.errMsg);
                        }
                        
                        resolve({
                            status: false,
                            message: `网络请求失败: ${err.errMsg || '未知错误'}`,
                            quota: {
                                used: 0,
                                available: 0,
                                isExceeded: false
                            }
                        });
                    }
                });
            });
        } catch (err) {
            console.error('【QA】检查配额出现异常:', err);
            if (err.errMsg) {
                console.error('【QA】错误消息:', err.errMsg);
            }
            
            return {
                status: false,
                message: `发生错误: ${err.errMsg || err.message || '未知错误'}`,
                quota: {
                    used: 0,
                    available: 0,
                    isExceeded: false
                }
            };
        }
    }
    
    /**
     * 获取并更新本地存储的使用情况
     * @private
     */
    _getStoredUsage() {
        try {
            // 尝试获取本地存储的使用次数
            let usageInfo = wx.getStorageSync('qa_api_usage') || {};
            
            // 获取今天的日期作为键
            const today = new Date().toISOString().split('T')[0]; // 格式如 "2023-06-15"
            
            // 如果没有今天的记录，初始化为0
            if (!usageInfo[today]) {
                usageInfo[today] = 0;
            }
            
            // 只保留最近7天的数据
            const keys = Object.keys(usageInfo).sort();
            if (keys.length > 7) {
                const keysToRemove = keys.slice(0, keys.length - 7);
                keysToRemove.forEach(key => {
                    delete usageInfo[key];
                });
            }
            
            return {
                used: usageInfo[today] || 0,
                daily: usageInfo
            };
        } catch (err) {
            console.error('【QA】获取本地使用记录失败:', err);
            return {
                used: 0,
                daily: {}
            };
        }
    }
    
    /**
     * 记录API使用次数
     * @private
     */
    _recordAPIUsage() {
        try {
            // 获取今天的日期作为键
            const today = new Date().toISOString().split('T')[0]; // 格式如 "2023-06-15"
            
            // 尝试获取本地存储的使用次数
            let usageInfo = wx.getStorageSync('qa_api_usage') || {};
            
            // 如果没有今天的记录，初始化为0
            if (!usageInfo[today]) {
                usageInfo[today] = 0;
            }
            
            // 增加使用次数
            usageInfo[today]++;
            
            // 保存回本地存储
            wx.setStorageSync('qa_api_usage', usageInfo);
        } catch (err) {
            console.error('【QA】记录API使用次数失败:', err);
        }
    }
}

module.exports = QAModel; 